package com.dlu.safe_construction.service.impl;

import com.dlu.safe_construction.common.ApiResult;
import com.dlu.safe_construction.common.CommonEnum;
import com.dlu.safe_construction.common.utils.Utils;
import com.dlu.safe_construction.dto.AreaInfoDTO;
import com.dlu.safe_construction.dto.SpaceInfoDTO;
import com.dlu.safe_construction.mapper.AreaMapper;
import com.dlu.safe_construction.mapper.CarMapper;
import com.dlu.safe_construction.mapper.OwnerMapper;
import com.dlu.safe_construction.mapper.SpaceMapper;
import com.dlu.safe_construction.model.Area;
import com.dlu.safe_construction.model.Car;
import com.dlu.safe_construction.model.Owner;
import com.dlu.safe_construction.model.Space;
import com.dlu.safe_construction.service.AreaService;
import com.dlu.safe_construction.service.SpaceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by  lijiaxing on 2022/3/31 21:57
 *
 * @author lijiaxing
 */
@Service
@Slf4j
public class SpaceServiceImpl implements SpaceService {

    @Resource
    private SpaceMapper spaceMapper;

    @Resource
    private AreaMapper areaMapper;

    @Resource
    private OwnerMapper ownerMapper;

    @Resource
    private CarMapper carMapper;


    //    for area add
    public int batchAdd(List<Space> spaces) {
        return spaceMapper.batchInsert(spaces);
    }

    private boolean addSpace(Space space) {
        Area area = areaMapper.selectByPrimaryKey(space.getAreaId());
        area.setSpaceNum(area.getSpaceNum() + 1);
        areaMapper.updateByPrimaryKey(area);
        return true;
    }

    @Override
    public ApiResult<Void> add(Space space) {
        int ret = spaceMapper.insertSelective(space);
        addSpace(space);
        return ApiResult.success();
    }

    private boolean deleteSpace(Space space) {
        Area area = areaMapper.selectByPrimaryKey(space.getAreaId());
        area.setSpaceNum(area.getSpaceNum() - 1);
        areaMapper.updateByPrimaryKey(area);
        return true;
    }

    @Override
    public ApiResult<Void> deleteBy(Space space, Integer byWhat) {
        if (CommonEnum.SpaceDeleteBy.DELETE_BY_SPACE_ID.isThisStatus(byWhat)) {
            int ret = spaceMapper.deleteBySpaceIdAndAreaId(space.getSpaceId(), space.getAreaId());
            boolean res = deleteSpace(space);
            return ApiResult.success();
        } else if (CommonEnum.SpaceDeleteBy.DELETE_BY_AREA_ID.isThisStatus(byWhat)) {
            int ret = spaceMapper.batchDeleteByAreaId(space.getAreaId());
            Area area = areaMapper.selectByPrimaryKey(space.getAreaId());
            area.setSpaceNum(0);
            areaMapper.updateByPrimaryKey(area);
            return ApiResult.success();
        }
        return ApiResult.fail(7003);
    }

    @Override
    public ApiResult<Void> edit(Space space) {
        int ret = spaceMapper.updateByPrimaryKeySelective(space);

        return ApiResult.success();
    }


    private List<SpaceInfoDTO> createFromSpaces(List<Space> spaces) {
        List<SpaceInfoDTO> spaceInfoDTOS = new ArrayList<>();
        spaces.stream().forEach(space -> {
            SpaceInfoDTO spaceInfoDTO = new SpaceInfoDTO();
            spaceInfoDTO.setSpaceId(space.getSpaceId());
            spaceInfoDTO.setAreaId(space.getAreaId());
            spaceInfoDTO.setCarId(space.getCarId());
            spaceInfoDTO.setSpaceStatus(space.getSpaceStatus());
            spaceInfoDTO.setSpaceTime(space.getSpaceTime());
            spaceInfoDTO.setId(space.getId());
            Car car = carMapper.selectByCarIdOne(space.getCarId());
            if (Utils.isNotEmpty(car)) {
                spaceInfoDTO.setOwnerId(car.getOwnerId());
                Owner owner = ownerMapper.selectByPrimaryKey(spaceInfoDTO.getOwnerId());
                spaceInfoDTO.setOwnerName(owner.getOwnerName());
                spaceInfoDTO.setOwnerPhone(owner.getOwnerPhone());
            }

            spaceInfoDTOS.add(spaceInfoDTO);
        });
        return spaceInfoDTOS;
    }

    @Override
    public ApiResult<List<AreaInfoDTO>> listAll() {
        List<Area> list = areaMapper.selectAll();
        List<AreaInfoDTO> areaInfoDTOs = new ArrayList<>();
        list.stream().forEach(area -> {
            List<Space> spaces = spaceMapper.selectByAreaId(area.getAreaId());
            areaInfoDTOs.add(AreaInfoDTO.fromArea(area, spaces));
        });
        return ApiResult.success(areaInfoDTOs);
    }

    @Override
    public ApiResult<List<SpaceInfoDTO>> searchBy(String key, Integer byWhat) {
        List<Space> list = null;
        if (CommonEnum.SpaceSearchBy.SEARCH_BY_SPACE_ID.isThisStatus(byWhat)) {
            list = new ArrayList<>();
            list.add(spaceMapper.selectBySpaceId(Integer.valueOf(key)));

        } else if (CommonEnum.SpaceSearchBy.SEARCH_BY_AREA_ID.isThisStatus(byWhat)) {
            list = spaceMapper.selectByAreaId(key);
        } else if (CommonEnum.SpaceSearchBy.SEARCH_BY_IN_SPACE_STATUS.isThisStatus(byWhat)) {
            list = spaceMapper.selectHaveCar();
        } else if (CommonEnum.SpaceSearchBy.SEARCH_BY_STATUS.isThisStatus(byWhat)) {
            list = spaceMapper.selectByStatus(Integer.valueOf(key));
        } else if (CommonEnum.SpaceSearchBy.SEARCH_BY_CAR_ID.isThisStatus(byWhat)) {
            list = spaceMapper.selectByCarId("%" + key + "%");
        } else if (CommonEnum.SpaceSearchBy.SEARCH_BY_OWNER_PHONE.isThisStatus(byWhat)) {
            List<String> carIds = getCarIdsByOwnerPhone(key);
            list = spaceMapper.selectByCarIds(carIds);
        }
        return ApiResult.success(createFromSpaces(list));
        //TODO 完善代码逻辑，编辑错误码及信息
    }

    private List<String> getCarIdsByOwnerPhone(String key) {
        List<String> ownerIds = getOwnerIds(key);
        List<Car> cars = carMapper.selectByOwnerIds(ownerIds);
        List<String> carIds = new ArrayList<>();
        cars.stream().forEach(car -> {
            carIds.add(car.getCarId());
        });
        return carIds;
    }

    private List<String> getOwnerIds(String key) {
        List<Owner> owners = ownerMapper.selectByOwnerPhone(key);
        List<String> ownerIds = new ArrayList<>();
        owners.stream().forEach(owner -> {
            ownerIds.add(owner.getOwnerId());
        });
        return ownerIds;
    }
}
